#include "GeradorCodigo.h"

/**
 * Construtor da classe
 * NoArvore & arvore No raiz da arvore sintatica
 * HashIdentificadores & hash Raiz da hash de identificadores contidos no programa
 * string nomeArquivo Nome do arquivo que devera conter a saida em mepa
 */
GeradorCodigo::GeradorCodigo(NoArvore& arvore, HashIdentificadores &hash, string nomeArquivo)
{
	this->mArvoreSintatica = &arvore;
	this->mHash = &hash;
	this->mLinhaAtual = 0;
	this->mUltimoDesvio = 0;//define o ultimo desvio valido
	this->mMemoriaAlocada = -1;
	this->mSaidaMepa = nomeArquivo;
	this->mArquivoMepa.IniciaCodigoGerado(this->mSaidaMepa.data());
	cout << endl << "Geracao de Codigo" << endl << endl;
	this->Tradutor(this->mArvoreSintatica->GetFilhos());//estao sendo passados como parametros os filhos do no raiz
	if(mMemoriaAlocada != -1)
		this->DesalocarMemoria(this->mMemoriaAlocada);
	this->Para();
	this->ImprimeArquivo();
}

/**
 * Solicita a impressao de uma linha no arquivo de saida e incrementa a linha atual (label)
 * string comando Comando a ser impresso no arquivo
 */
void GeradorCodigo::ImprimeLinha(string comando)
{
	this->mLinhaMepa.push_back(comando);
	this->mLinhaAtual++;
}

void GeradorCodigo::ImprimeArquivo()
{
	for(unsigned int cont = 0; cont < this->mLinhaMepa.size(); cont++)
		this->mArquivoMepa.ImprimeCodigoGerado(this->mSaidaMepa.data(), cont, this->mLinhaMepa.at(cont));
}

void GeradorCodigo::CarregarConstante(string constante)
{
	string comando = "CRCT ";
	/*ostringstream value;
	value << constante;*/
	comando = comando + constante;//value.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::CarregaValor(int valor, int n)
{
	string comando = "CRVL ";
	ostringstream value, n1;
	value << valor;
	comando = comando + value.str();
	comando = comando + ",";
	n1 << n;
	comando = comando + n1.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::Soma()
{
	this->ImprimeLinha("SOMA");
}

void GeradorCodigo::Subtracao()
{
	this->ImprimeLinha("SUBT");
}

void GeradorCodigo::Multiplicacao()
{
	this->ImprimeLinha("MULT");
}

void GeradorCodigo::Divisao()
{
	this->ImprimeLinha("DIVI");
}

void GeradorCodigo::InverteSinal()
{
	this->ImprimeLinha("INVR");
}

//comando AND
void GeradorCodigo::Conjuncao()
{
	this->ImprimeLinha("CONJ");
}

//comando OR
void GeradorCodigo::Disjuncao()
{
	this->ImprimeLinha("DISJ");
}

void GeradorCodigo::Negacao()
{
	this->ImprimeLinha("NEGA");
}

void GeradorCodigo::ComparaMenor()
{
	this->ImprimeLinha("CMME");
}

void GeradorCodigo::ComparaMaior()
{
	this->ImprimeLinha("CMMA");
}

void GeradorCodigo::ComparaIgual()
{
	this->ImprimeLinha("CMIG");
}

void GeradorCodigo::ComparaDesigual()
{
	this->ImprimeLinha("CMDG");
}

void GeradorCodigo::ComparaMenorIgual()
{
	this->ImprimeLinha("CMEG");
}

void GeradorCodigo::ComparaMaiorIgual()
{
	this->ImprimeLinha("CMAG");
}

void GeradorCodigo::ArmazenaValor(int valor, int n)
{
	string comando = "ARMZ ";
	ostringstream value, n1;
	value << valor;
	comando = comando + value.str();
	comando = comando + ",";
	value.flush();
	n1 << n;
	comando = comando + n1.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::DesviarSempre(int identificador)
{
	string comando = "DSVS ";
	ostringstream ident;
	ident << identificador;
	comando = comando + ident.str();
	this->ImprimeLinha(comando);
}

string GeradorCodigo::RetDesviarSempre(int identificador)
{
	string comando = "DSVS ";
	ostringstream ident;
	ident << identificador;
	comando = comando + ident.str();
	return comando;
}

void GeradorCodigo::DesviarSeFalso(int identificador)
{
	string comando = "DSVF ";
	ostringstream ident;
	ident << identificador;
	comando = comando + ident.str();
	this->ImprimeLinha(comando);
}

string GeradorCodigo::RetDesviarSeFalso(int identificador)
{
	string comando = "DSVF ";
	ostringstream ident;
	ident << identificador;
	comando = comando + ident.str();
	return comando;
}

void GeradorCodigo::Nada()
{
	this->ImprimeLinha("NADA");
}

void GeradorCodigo::Leitura()
{
	this->ImprimeLinha("LEIT");
}

void GeradorCodigo::Imprimir()
{
	this->ImprimeLinha("IMPR");
}

void GeradorCodigo::ImprimirPularLinha()
{
	this->ImprimeLinha("IMPL");
}

void GeradorCodigo::ImprimirCaractere()
{
	this->ImprimeLinha("IMPC");
}

void GeradorCodigo::IniciaProgramaPrincipal()
{
	this->ImprimeLinha("INPP");
}

void GeradorCodigo::AlocarMemoria(int quantidade)
{
	string comando = "AMEM ";
	ostringstream qtd;
	qtd << quantidade;
	comando = comando + qtd.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::Para()
{
	this->ImprimeLinha("PARA");
}

void GeradorCodigo::ChamarProcedimento(int endereco)
{
	string comando = "CHPR ";
	ostringstream end;
	end << endereco;
	comando = comando + end.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::EntrarProcedimento(int nivel)
{
	string comando = "ENPR ";
	ostringstream nvl;
	nvl << nivel;
	comando = comando + nvl.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::RetornarProcedimento(int nivel)
{
	string comando = "RTPR ";
	ostringstream nvl;
	nvl << nivel;
	comando = comando + nvl.str();
	this->ImprimeLinha(comando);
}
int GeradorCodigo::RetLabel(string mNome)
{
	for(unsigned int i = 0 ; i < this->mLabel.size(); i++)
	{
		if(mNome == mLabel.at(i).funcao)
		{
			return mLabel.at(i).linha;
		}
	}
	return -1;
}


void GeradorCodigo::DesalocarMemoria(int quantidade)
{
	string comando = "DMEM ";
	ostringstream qtd;
	qtd << quantidade;
	comando = comando + qtd.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::CarregaValorIndireto(int k, int n)
{
	string comando = "CRVI ";
	ostringstream valor, n1;
	valor << k;
	comando = comando + valor.str();
	n1 << n;
	comando = comando + ",";
	comando = comando + n1.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::ArmazenaValorIndireto(int k, int n)
{
	string comando = "ARMI ";
	ostringstream valor, n1;
	valor << k;
	comando = comando + valor.str();
	n1 << n;
	comando = comando + ",";
	comando = comando + n1.str();
	this->ImprimeLinha(comando);
}

void GeradorCodigo::CarregaEndereco(int k, int n)
{
	string comando = "CREN ";
	ostringstream valor, n1;
	valor << k;
	comando = comando + valor.str();
	n1 << n;
	comando = comando + ",";
	comando = comando + n1.str();
	this->ImprimeLinha(comando);
}
//DECLARA PROCEDIMENTO
void GeradorCodigo::DeclaraProcedimento(vector<NoArvore *> filhos)
{

	
	
	
	//<procedure> <nada> <PARAMETROS FORMAIS> <;> <BLOCO> 
	this->EntrarProcedimento(filhos.at(1)->GetNivel());
	
	//SETAR O LABEL COM A LINHA E NOME DO PROCEDIMENTO
	label mPosicao;
	mPosicao.linha = this->mLinhaAtual;
	
	
	mPosicao.funcao = filhos.at(1)->GetToken();
	//insere o label da funcao
	this->mLabel.push_back(mPosicao);	
					
				
	if(filhos.at(2)->GetToken() == "PARAMETROS FORMAIS")
	{
		
		//filhos de PARAMENTROS FORMAIS
		vector<NoArvore *> mParamtrosFormais = filhos.at(2)->GetFilhos();
		int memoriaAlocada = -1;
		if(mParamtrosFormais.at(0)->GetToken() == "var")
		{
			//PASSAGEM POR VALOR
	
			int vars = 0;
			for(unsigned int cont = 0; cont < mParamtrosFormais.size(); cont++)
			{
				if(mParamtrosFormais.at(cont)->GetToken() == "boolean" || mParamtrosFormais.at(cont)->GetToken() == "integer")
					vars++;
			}
			if(vars > 1)
			{
				this->AlocarMemoria(mParamtrosFormais.size() - 3 - vars);
				memoriaAlocada = mParamtrosFormais.size() - 3 - vars;
			}
			else
			{
				this->AlocarMemoria(mParamtrosFormais.size() - 3);
				memoriaAlocada = mParamtrosFormais.size() - 3;
			}
		
			
			//deve-se saber o deslocamento
			NoHash* mFuncao = this->mHash->PesquisaVariavelNivel(filhos.at(1)->GetToken(), filhos.at(1)->GetNivel());
				
			
			//passa para verficar o procedimento
			if(filhos.size() == 5 )
			{
					Tradutor(filhos.at(4)->GetFilhos());
					this->DesalocarMemoria(memoriaAlocada);
					RetornarProcedimento(filhos.at(2)->GetNivel() );
					return;
			}else
			{
				
					//chamda para funcao
					Tradutor(filhos.at(6)->GetFilhos());
					this->DesalocarMemoria(memoriaAlocada);
					RetornarProcedimento(filhos.at(2)->GetNivel() );
					return;
				
			}
			
		}else
		{

				//PASSAGEM POR VALOR
				//deve-se saber o deslocamento
				NoHash* mFuncao = this->mHash->PesquisaVariavelNivel(filhos.at(1)->GetToken(), filhos.at(1)->GetNivel());
				for (int k = 0 ; k < mFuncao->getNumParametros() ;k++)
				{
						CarregaValor(filhos.at(1)->GetNivel(),mFuncao->GetDeslocamento(k));
						
				}
				//passa para verficar o procedimento
				if(filhos.size() == 5 )
				{
						Tradutor(filhos.at(4)->GetFilhos());
						this->DesalocarMemoria(memoriaAlocada);
						RetornarProcedimento(filhos.at(2)->GetNivel());
						return;
				}else
				{
					
						//chamda para funcao
						Tradutor(filhos.at(6)->GetFilhos());
						this->DesalocarMemoria(memoriaAlocada);
						RetornarProcedimento(filhos.at(2)->GetNivel());
						return;
					
				}
				
		}
		
	}
	//chama procedimento sem parametro
	RetornarProcedimento(filhos.at(2)->GetNivel() );
	Tradutor(filhos.at(3)->GetFilhos());
	return;
			
	
}

//os primeiros que recebo sao os filhos do no raiz
void GeradorCodigo::Tradutor(vector<NoArvore *> filhos)
{
	cout << filhos.at(0)->GetToken()<<endl;
	if(filhos.at(0)->GetToken() == "program")
		this->IniciaProgramaPrincipal();

	for(unsigned int i = 0; i < filhos.size(); i++)
	{
		// PARTE DE CHAMADA DE PROCEDIMENTO E FUNCAO
		if(filhos.at(i)->GetToken() == "PARTE DECLARACAO PROCEDIMENTO"
		|| filhos.at(i)->GetToken() == "PARTE DECLARACAO FUNCAO")
		{
			// MARCA A LINHA ONDE SERA DADO O DESVIO COM VALOR QUALQUER
			// QUANDO SAIR DA FUNCAO A LINHA SERA SETADA COM VALOR CORRETO
			this->DesviarSempre(10);
			int mRetorno = this->mLinhaMepa.size();
			
			//CHAMA METODO PARA ANALISE
			DeclaraProcedimento(filhos.at(i)->GetFilhos());
			
			//IMPRIME O RETORNO NO ARQUIVO
			this->Nada();
			this->mLinhaMepa[mRetorno-1] = this->RetDesviarSempre(this->mLinhaAtual-1);
			continue;
		}
		

		//CHAMADA DE FUNCAO TERMINA AQUI

		if(filhos.at(i)->IsTerminal() || filhos.at(i)->GetAvaliado())//se terminal nao tem filhos ou se ja foi avaliado
		{	
			if(filhos.at(i)->IsTerminal())
			{
				NoHash *mNo = this->mHash->Pesquisa(filhos.at(i)->GetToken());
				// procedimento ou funcao
				if(mNo != NULL && mNo->GetCategoria() != 0)
				{
					//tenho uma funcao devo descubrir o label
					int label = this->RetLabel(mNo->GetId())-1;
					
					for(unsigned int cont = 0; cont < filhos.size(); cont++)
					{
						if(!filhos.at(cont)->IsTerminal())
						{
							vector<NoArvore *> exp = filhos.at(cont)->GetFilhos();
							this->SetaAvaliado(exp);
							exp = exp.at(0)->GetFilhos();
							this->SetaAvaliado(exp);
							exp = exp.at(0)->GetFilhos();
							//chamo para fator
							Tradutor(exp);
							this->SetaAvaliado(exp);
						}
					}
					this->ChamarProcedimento(label);
					this->SetaAvaliado(filhos);
				}
			}				
				continue;//entao volto para o inicio do for
		}
		vector<NoArvore *> netos = filhos.at(i)->GetFilhos();
		
		if(filhos.at(i)->GetToken() == "PARTE DECLARACAO VARIAVEIS")
		{
			int vars = 0;
			for(unsigned int cont = 0; cont < netos.size(); cont++)
			{
				if(netos.at(cont)->GetToken() == "boolean" || netos.at(cont)->GetToken() == "integer")
					vars++;
			}
			if(vars > 1)
			{
				this->AlocarMemoria(netos.size() - 3 - vars);
				this->mMemoriaAlocada = netos.size() - 3 - vars;
			}
			else
			{
				this->AlocarMemoria(netos.size() - 3);
				this->mMemoriaAlocada = netos.size() - 3;
			}
		}
		
		
		if(filhos.at(0)->GetToken() == "ATRIBUICAO")
		{
			this->SetaAvaliado(filhos);
			vector<NoArvore *> variavel = filhos.at(0)->GetFilhos();
			this->SetaAvaliado(variavel);
			vector<NoArvore *> expressao = variavel.at(2)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);

			for(unsigned int cont = 0; cont < expressao.size(); cont++)
			{
				if(!expressao.at(cont)->IsTerminal())
				{
					vector<NoArvore *> exp = expressao.at(cont)->GetFilhos();//neste momento tenho um fator
					Tradutor(exp);
					this->SetaAvaliado(exp);
					if(cont == 2)
					{
						if(expressao.at(cont - 1)->GetToken() == "+")
							this->Soma();
						else if(expressao.at(cont - 1)->GetToken() == "-")
							this->Subtracao();
						else if(expressao.at(cont - 1)->GetToken() == "*")
							this->Multiplicacao();
						else if(expressao.at(cont - 1)->GetToken() == "or")
							this->Disjuncao();
						else if(expressao.at(cont - 1)->GetToken() == "div")
							this->Divisao();
						else if(expressao.at(cont - 1)->GetToken() == "and")
							this->Conjuncao();
					}
						
				}
				else
				{
					if(cont > 1)
					{
						if(expressao.at(cont - 1)->GetToken() == "+")
							this->Soma();
						else if(expressao.at(cont - 1)->GetToken() == "-")
							this->Subtracao();
						else if(expressao.at(cont - 1)->GetToken() == "or")
							this->Disjuncao();
					}
				}
			}
			NoHash* var = this->mHash->Pesquisa(variavel.at(0)->GetToken());
			this->ArmazenaValor(var->GetNivel(), var->RetDeslocamento());
		}
		
		if(filhos.at(0)->GetToken() == "write" || filhos.at(0)->GetToken() == "writeln")
		{
			this->SetaAvaliado(filhos);
			vector<NoArvore *> expressao = filhos.at(2)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			Tradutor(expressao.at(0)->GetFilhos());
			this->SetaAvaliado(expressao);
			if(filhos.at(0)->GetToken() == "write")
				this->Imprimir();
			else
				this->ImprimirPularLinha();
		}
		
		if(filhos.at(0)->GetToken() == "read")
		{
			this->SetaAvaliado(filhos);

			for(unsigned int cont = 0; cont < filhos.size(); cont++)
			{
				if(!filhos.at(cont)->IsTerminal())
				{
					vector<NoArvore *> expressao = filhos.at(cont)->GetFilhos();
					this->SetaAvaliado(expressao);
					expressao = expressao.at(0)->GetFilhos();
					this->SetaAvaliado(expressao);
					expressao = expressao.at(0)->GetFilhos();
					this->SetaAvaliado(expressao);
					expressao = expressao.at(0)->GetFilhos();
					this->SetaAvaliado(expressao);
					expressao = expressao.at(0)->GetFilhos();
					this->SetaAvaliado(expressao);
					//neste ponto tenho as variaveis da expressao
					NoHash* var = this->mHash->Pesquisa(expressao.at(0)->GetToken());
					this->Leitura();
					this->ArmazenaValor(var->GetNivel(), var->RetDeslocamento());
				}
			}
			this->SetaAvaliado(filhos);
		}
		
		if(filhos.at(0)->GetToken() == "not")
		{
			if(filhos.size() > 1)
			{
				for(unsigned int cont = 1; cont < filhos.size(); cont++)
				{
					vector<NoArvore *> gambi;
					gambi.push_back(filhos.at(cont));
					Tradutor(gambi);
				}
			}
		}
		
		if(filhos.at(0)->GetToken() == "FATOR")
		{
			for(unsigned int cont = 0; cont < filhos.size(); cont++)
			{
				if(!filhos.at(cont)->IsTerminal())
				{
					vector<NoArvore *> fat = filhos.at(cont)->GetFilhos();
					if(fat.at(0)->GetToken() == "NUMERO")
					{
						this->SetaAvaliado(fat);
						vector<NoArvore *> num = fat.at(0)->GetFilhos();
						this->SetaAvaliado(num);
						this->CarregarConstante(num.at(0)->GetToken());
					}
					if(fat.at(0)->GetToken() == "VARIAVEL")
					{
						this->SetaAvaliado(fat);
						vector<NoArvore *> v = fat.at(0)->GetFilhos();
						NoHash* var = this->mHash->Pesquisa(v.at(0)->GetToken());
						this->CarregaValor(var->GetNivel(), var->RetDeslocamento());
					}
					if(cont == 2)
					{
						if(filhos.at(cont - 1)->GetToken() == "*")
							this->Multiplicacao();
						if(filhos.at(cont - 1)->GetToken() == "div")
							 this->Divisao();
						else if(filhos.at(cont - 1)->GetToken() == "and")
							 this->Conjuncao();
					}
				}
				else if(cont > 1)
				{
					if(filhos.at(cont)->GetToken() == "*")
						this->Multiplicacao();
					if(filhos.at(cont)->GetToken() == "div")
						 this->Divisao();
					else if(filhos.at(cont)->GetToken() == "and")
						 this->Conjuncao();
				}
			}
			this->SetaAvaliado(filhos);
		}
		
		if(filhos.at(i)->GetToken() == "RELACAO")
		{
			vector<NoArvore *> relacao = filhos.at(i)->GetFilhos();
			
			if(relacao.at(0)->GetToken() == "=")
				this->ComparaIgual();
			else if(relacao.at(0)->GetToken() == "<>")
				this->ComparaDesigual();
			else if(relacao.at(0)->GetToken() == "<")
				this->ComparaMenor();
			else if(relacao.at(0)->GetToken() == "<=")
				this->ComparaMenorIgual();
			else if(relacao.at(0)->GetToken() == ">=")
				this->ComparaMaiorIgual();
			else if(relacao.at(0)->GetToken() == ">")
				this->ComparaMaior();
			this->SetaAvaliado(relacao);
		}
		
		if(filhos.at(0)->GetToken() == "if")
		{
			bool hasElse = false;
			vector<NoArvore *> noElse;
			if(filhos.size() > 5)
				hasElse = true;

			//como se trata de um if indice 1 eh a expressao do if
			vector<NoArvore *> expressao = filhos.at(1)->GetFilhos();
			vector<NoArvore *> then = filhos.at(3)->GetFilhos();
			if(hasElse)
				noElse = filhos.at(5)->GetFilhos();
			
			this->SetaAvaliado(filhos);
			//tratando a expressao
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(1)->GetFilhos();//(expressao)
			
			bool hasNot = false;
			for(unsigned int cont = 0; cont < expressao.size(); cont++)
			{
				if(expressao.at(cont)->GetToken() != "RELACAO")
				{
					vector<NoArvore *>expSimples = expressao.at(cont)->GetFilhos();

					expSimples = expSimples.at(0)->GetFilhos();

					vector<NoArvore *>temp;
					temp = expSimples.at(0)->GetFilhos();
					if(temp.at(0)->GetToken() == "not")
					{
						hasNot = true;
					}
					
					Tradutor(expSimples);
					this->SetaAvaliado(expSimples);
				}
			}
			Tradutor(expressao);
			this->SetaAvaliado(expressao);
			
			if(hasNot)
				this->Negacao();
			
			//condicao falsa pula pro else
			this->mDesvios.push(this->mLinhaAtual);
			this->mUltimoDesvio = this->mLinhaAtual;//desvio a alterar
			this->DesviarSeFalso(this->mLinhaAtual);
			
			//tratando o then
			Tradutor(then);
			this->SetaAvaliado(then);

			int fimThen = -1;
			if(hasElse)
			{
				//se tem else, no fim do then pulo fora
				fimThen = this->mLinhaAtual;
				this->DesviarSempre(this->mLinhaAtual);
				this->Nada();
				this->mLinhaMepa[this->mDesvios.top()] = this->RetDesviarSeFalso(this->mLinhaAtual-1);
				this->mDesvios.pop();
				Tradutor(noElse);
			}
			
			//fim de todo o comando if
			this->Nada();
			if(fimThen != -1)
				this->mLinhaMepa[fimThen] = this->RetDesviarSempre(this->mLinhaAtual-1);
		}
		
		if(filhos.at(0)->GetToken() == "while")
		{
			this->Nada();
			this->SetaAvaliado(filhos);
			//linha de inicio do while
			this->mUltimoDesvio = this->mLinhaAtual-1;
			this->mDesvios.push(this->mLinhaAtual-1);
			vector<NoArvore *> expressao = filhos.at(1)->GetFilhos();
			vector<NoArvore *> comandos = filhos.at(3)->GetFilhos();
			//primeiro a expressao
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(0)->GetFilhos();
			this->SetaAvaliado(expressao);
			expressao = expressao.at(1)->GetFilhos();
			
			bool hasNot = false;
			for(unsigned int cont = 0; cont < expressao.size(); cont++)
			{
				if(expressao.at(cont)->GetToken() != "RELACAO")
				{
					vector<NoArvore *> expressaoSimples = expressao.at(cont)->GetFilhos();
					expressaoSimples = expressaoSimples.at(0)->GetFilhos();
					
					vector<NoArvore *>temp;
					temp = expressaoSimples.at(0)->GetFilhos();
					if(temp.at(0)->GetToken() == "not")
					{
						hasNot = true;
					}
					
					Tradutor(expressaoSimples);
					this->SetaAvaliado(expressaoSimples);
				}
			}
			Tradutor(expressao);//chamo para relacao
			this->SetaAvaliado(expressao);
			if(hasNot)
				this->Negacao();
			
			//condicao pra sair do while
			this->DesviarSeFalso(this->mLinhaAtual);//isso ta errado!!!!
			int seFalso = this->mLinhaAtual - 1;
			//tratando comandos a serem realizados dentro do while
			for(unsigned int cont = 0; cont < comandos.size(); cont++)
			{
				vector<NoArvore *> cmd;
				if(!comandos.at(cont)->IsTerminal())
				{
					cmd = comandos.at(cont)->GetFilhos();
					this->SetaAvaliado(cmd);
					//tratando comando
					cmd = cmd.at(0)->GetFilhos();
					Tradutor(cmd);
					this->SetaAvaliado(cmd);
				}

			}
			this->SetaAvaliado(comandos);
			this->DesviarSempre(this->mDesvios.top());
			this->mDesvios.pop();
			this->Nada();
			this->mLinhaMepa[seFalso] = this->RetDesviarSeFalso(this->mLinhaAtual-1);
		}
		
		this->Tradutor(netos);
	}
}

void GeradorCodigo::SetaAvaliado(vector<NoArvore *> no)
{
	for(unsigned int i = 0; i < no.size(); i++)
	{
		no.at(i)->SetAvaliado();
	}
}

GeradorCodigo::~GeradorCodigo()
{
}
